;; decode JSON file into lisp struct

;; (defstruct place id name in note)
;; (defstruct quantity id name type in note) 
;; (defstruct claim id cause effect direction note)
;; (defstruct fact id from to direction note) 
;; (defstruct prediction id from to direction paths)

(load "newqual")
(load-content "mito.lisp")

(require :yason)

(defun maybe-convert-to-keyword (js-name)
           (or (find-symbol (string-upcase js-name) :keyword)
               js-name))

(defun decode-json-places (*filename*)
  (defvar decoded-places* ())
  (setq decoded-places* ())
  (with-open-file (stream *filename*)
    (let* ((json:*parse-object-key-fn* #'maybe-convert-to-keyword)
	   (json:*parse-json-arrays-as-vectors* t)
	   (result (json:parse stream)))
      (loop for r being the elements of result do
	   (let* ((id (intern (gethash :ID r)))
		  (name (intern (gethash :NAME r)))
		  (in (intern (gethash :IN r)))
		  (note (intern (gethash :NOTE r))))
	     (setq p (make-place :id id :name name :in in :note note))
	     (push p decoded-places*)))))
  (setq decoded-places* (reverse decoded-places*)))


(defun decode-json-quantities (*filename*)
  (defvar decoded-quantities* ())
  (setq decoded-quantities* ())
  (with-open-file (stream *filename*)
    (let* ((json:*parse-object-key-fn* #'maybe-convert-to-keyword)
	   (json:*parse-json-arrays-as-vectors* t)
	   (result (json:parse stream)))
      (loop for r being the elements of result do
	   (let* ((id (intern (gethash :ID r)))
		  (name (intern (gethash :NAME r)))
		  (type (intern (gethash :TYPE r)))
		  (in (intern (gethash :IN r)))
		  (note (intern (gethash :NOTE r))))
	     (setq q (make-quantity :id id :name name :type type :in in :note note))
	     (push q decoded-quantities*)))))
  (setq decoded-quantities* (reverse decoded-quantities*)))


(defun decode-json-claims (*filename*)
  (defvar decoded-claims* ())
  (setq decoded-claims* ())
  (with-open-file (stream *filename*)
    (let* ((json:*parse-object-key-fn* #'maybe-convert-to-keyword)
	   (json:*parse-json-arrays-as-vectors* t)
	   (result (json:parse stream)))
      (loop for r being the elements of result do
	   (let* ((id (intern (gethash :ID r)))
		  (cause (intern (gethash :CAUSE r)))
		  (effect (intern (gethash :EFFECT r)))
		  (direction (intern (gethash :DIRECTION r)))
		  (note (intern (gethash :NOTE r))))
	     (setq c (make-claim :id id :cause cause :effect effect :direction direction :note note))
	     (push c decoded-claims*)))))
  (setq decoded-claims* (reverse decoded-claims*)))

(defun decode-json-facts (*filename*)
  (defvar decoded-facts* ())
  (setq decoded-facts* ())
  (with-open-file (stream *filename*)
    (let* ((json:*parse-object-key-fn* #'maybe-convert-to-keyword)
	   (json:*parse-json-arrays-as-vectors* t)
	   (result (json:parse stream)))
      (loop for r being the elements of result do
	   (let* ((id (intern (gethash :ID r)))
		  (from (intern (gethash :FROM r)))
		  (to (intern (gethash :TO r)))
		  (direction (intern (gethash :DIRECTION r)))
		  (note (intern (gethash :NOTE r))))
	     (setq f (make-fact :id id :from from :to to :direction direction :note note))
	     (push f decoded-facts*)))))
  (setq decoded-facts* (reverse decoded-facts*)))

(defun decode-json-predictions (*filename*)
  (defvar decoded-predictions* ())
  (setq decoded-predictions* ())
  (with-open-file (stream *filename*)
    (let* ((json:*parse-object-key-fn* #'maybe-convert-to-keyword)
	   (json:*parse-json-arrays-as-vectors* t)
	   (result (json:parse stream)))
      (loop for r being the elements of result do
	   (let* ((id (intern (gethash :ID r)))
		  (from (intern (gethash :FROM r)))
		  (to (intern (gethash :TO r)))
		  (direction (intern (gethash :DIRECTION r)))
		  (paths (intern (gethash :PATHS r))))
	     (setq f (make-prediction :id id :from from :to to :direction direction :paths paths))
	     (push f decoded-predictions*)))))
  (setq decoded-predictions* (reverse decoded-predictions*)))

